﻿using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

namespace Learning
{
    public class ColorIntensityRenderPass : ScriptableRenderPass
    {
        public ColorIntensitySetting setting;

        public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
        {
        }

        public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
        {
        }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
#if UNITY_EDITOR
            // 如果不希望 Scene 窗口下执行该Pass（只有Game执行，避免影响Scene窗口下查看原始），可以添加这个检测排查掉 SceneCamera（该摄像机是Scene窗口的相机，是看不见的）
            // 也可以通过判定其它相机来做剔除，不过一般来说摄像机可以选择自己的Renderer，所以这里的判定一般用于排除 SceneCamera
            if (renderingData.cameraData.camera != Camera.main)
            {
                return;
            }
#endif
            
            if (setting.material == null)
            {
                return;
            }

            /// 注意：未显式释放的所有临时纹理都将在摄像机完成渲染后被统一释放
            
            // 新建 RT
            RenderTextureDescriptor rt = new RenderTextureDescriptor(Camera.main.pixelWidth, Camera.main.pixelHeight, RenderTextureFormat.Default, 0);
            RenderTexture rtTex = RenderTexture.GetTemporary(rt);
            
            // 获取相机的RT
            RenderTargetIdentifier cameraColorTexture = renderingData.cameraData.renderer.cameraColorTarget;

            // 获取一个新的命令缓冲区，并分配一个名称，该名字会在FrameDebug窗口显示
            CommandBuffer cmd = CommandBufferPool.Get(name: "ColorIntensityRenderPass");

            // 设定参数
            setting.material.SetFloat("_Intensity", setting.intensity);
            setting.material.SetColor("_Color", setting.featureColor);

            /// 注意：后处理的 Shader 里面，主贴图的名称必须是 _MainTex 否则无法正常渲染回摄像机
            
            // 对相机里面的画面进行一些操作，将相机获取到的RT图，通过material材质的计算，输出到rtTex
            Blit(cmd, cameraColorTexture, rtTex, setting.material);
            // 将上一步的rtTex，重新写回相机
            Blit(cmd, rtTex, cameraColorTexture);

            // 存在RT资源就将当前抓取的图像写入RT
            if (setting.renderTexture != null)
            {
                Blit(cmd, rtTex, setting.renderTexture);
            }

            // 执行缓冲区并清空和回收缓冲
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            CommandBufferPool.Release(cmd);
        }

        public override void OnCameraCleanup(CommandBuffer cmd)
        {
        }
    }
}
